#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
.. module:: console
    :synopsis: Interaction with the command-line.

Overview
~~~~~~~~
This module provides the code for the user to control Croquette
primarily by using the command-line.  It relies heavily on
`argparse`_, a command-line parser found in the standard Python
library.

.. _argparse: http://docs.python.org/library/argparse.html

Usage
~~~~~
Arguments
---------
The arguments you can use will depend on which mode you set Croquette
to.  For example, `python croquette.exe interpreter -t` will cause the
interpreter to run the tokenizer, whereas
`python croquette.exe converter -t` will cause the converter to indent
any converted code.  In both cases, the argument `-t` was used, but the
mode was set differently.

Arguements:

.. program:: python croquette converter <filename>

    The filename is either the .txt or .8xp file to attempt to convert.
    If the file is an .8xp, Croquette will automatically attempt to
    convert it to a text file in the appropriate language (Axe or Basic).

    If it is a .txt file, the file will be converted to an .8xp file.

.. option:: -c, --colons

    This will prefix the start of each line in a text file with a
    colon.  Off by default.

.. option:: -t <amount>, --tabs <amount>

    If present, will indent the output .txt file the correct number
    of spaces.  You can optionally chose to specify the number of
    spaces per each indent.  For example, using `--tabs 5` will
    result in 5 spaces per indent.  Off by default.

.. option:: -f <language>, --force <language>

    Forces the converter to detokenize an .8xp into a specified
    language.  If you have an .8xp file written in TI-Basic, for
    example, you could call `--force axe` to force the output
    .txt to use Axe tokens.  Alternatively, you could use
    `--force basic` to make certain that the output would be
    in TI-Basic.  The converter will automatically attempt to
    detect the appropiate language.

    `<language>` can be either `axe` or `basic`.

.. option:: -e <name>, --encoding <name>

    Each language (Axe and Basic) is defined by an .xml file.  It's
    possible to specify different text for each token.  For
    example, in Axe, the `log(` key could be represented by
    `log(`, `lambda(`, or `λ(`, depending on the encoding
    specified.

    In the default Axe and TI-Basic xml files provided
    by the program, there are only two encodings -- `normal` and
    `fancy`.  Using `--encoding fancy` would cause code to look
    like this: ::

        λ(r1*r2+r3)→L
        If A
            L(3,B,C)→C
        End

    whereas using `--encoding normal` would cause the same code
    to look like this: ::

        lambda(r1*r2+r3)->:
        If A
            L(3,B,C)->C
        End

    Custom language files may include different encodings.

.. option:: -l <language>, --language <language>

    Croquette


Code
----
Using this module via Python code is fairly simple. You simply need
to initialize an instance of :py:class: `CommandIo` and run
:py:meth: `parse` to run it.  ::

    >>> command_io = CommandIo()
    >>> command_io.parse()

This will automatically scrape all arguments from the command-line and
run it accordingly.

To feed it specific commands, feed :py:meth: `parse` a list of arguments. ::

    >>> command_io = CommandIo()
    >>> arguments = command_io.parse(["console", "--tabs", "4"])

Contents
~~~~~~~~

Classes
-------
:py:class: `CommandIo()`
    :py:meth: `parse()`
    :py:meth: `_create_parser()`
    :py:meth: `_create_subparsers()`
    :py:meth: `_add_arguments()`

Functions
---------
:py:function: `main()`

Meta
~~~~
.. moduleauthor:: Michael Lee <michael.lee.0x2a@gmail.com>
"""

## Standard Library Imports ##
from __future__ import print_function
import os, os.path
import argparse

## Program Components ##
#import meta

class meta(object):
    short_description = 'description'
    program_name = 'Croquette'
    version = '1.1'


class CommandIo():
    """
    Interacts with the command-line.

    .. py:class:: CommandIO()

    """
    def __init__(self):
        """
        Initializes the parser and sets up the arguments.

        .. py:method:: __init__()
        """
        self._create_parser()
        self._add_arguments()
        self._create_subparsers()
        return

    def _create_parser(self):
        """
        Creates the actual parser.  This is called during initialization.

        .. py:method:: _create_parser()
        """
        self._parser = argparse.ArgumentParser(
            description=meta.short_description,
            add_help=True,
            prog=meta.program_name)
        return

    def _create_subparsers(self):
        """
        Creates subparsers.


        """
        self._subparsers = self._parser.add_subparsers()
        #self._gui_subparser = GuiSubparser(self._subparsers)
        #self._console_subparser = ConsoleSubparser(self._subparsers)
        #self._interpreter_subparser = InterpreterSubparser(self._subparser)
        return

    def _add_arguments(self):
        ## Callbacks ##
        class _LicenseCallback(argparse.Action):
            def __call__(self, parser, namespace, values, option_string=None):
                print(meta.license)
                return

        class _AboutCallback(argparse.Action):
            def __call__(self, parser, namespace, values, option_string=None):
                print(meta.description)
                return
        
        self._parser.add_argument(
            '-v', '--version',
            action='version',
            version=meta.version,
            help="Displays the version and release date."
        )
        self._parser.add_argument(
            '--license',
            action=_LicenseCallback,
            help="Displays the license."
        )
        self._parser.add_argument(
            '--about',
            action=_AboutCallback,
            help="Gives more detailed information about the program"
        )
        return

    def parse(self):
        pass

    def _add_meta_arguments(self):
        pass

def main():
    """Reads input from the command line, and converts the files."""
    commandio = CommandIo()
    options = commandio.parse()

if __name__ == "__main__":
    main()
